package report

import (
	"context"
	"git.mycaigou.com/gfyx/common/authorize"
	"git.mycaigou.com/gfyx/common/http_client"
	"git.mycaigou.com/gfyx/common/rpc_client"
	"git.mycaigou.com/gfyx/common/simplecopier"
	reportDto "git.mycaigou.com/gfyx/micro-gfyx-mp-api/http_server/dto/report"
	"git.mycaigou.com/gfyx/micro-gfyx-mp-api/infrastructure/common/constants"
	cluePb "git.mycaigou.com/gfyx/micro-gfyx-mp-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/clue"
	commonPb "git.mycaigou.com/gfyx/micro-gfyx-mp-api/proto/micro_gfyx_oppty_service_proto/micro-gfyx-oppty-service/common"
	microGfyxUserService "git.mycaigou.com/gfyx/micro-gfyx-mp-api/proto/micro_gfyx_user_service_proto/micro-gfyx-user-service"
	report2 "git.mycaigou.com/gfyx/micro-gfyx-mp-api/service/clue/report"
	"git.myscrm.cn/golang/stark/v4"
	"strings"
)

type reportRepository struct {
}

// NewReportRepository 报备
func NewReportRepository() report2.ReportRepositoryIface {
	return &reportRepository{}
}

func (r *reportRepository) GetFormTemplateConfig(ctx context.Context, templateId string) ([]map[string]interface{}, error) {
	request := &commonPb.GetFormTemplateConfigRequest{
		TemplateId: templateId,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := commonPb.NewFormServiceClient(conn)
	resp, err := client.GetFormTemplateConfig(ctx, request)
	if err != nil {
		return nil, err
	}
	if resp == nil {
		return nil, nil
	}

	result, err := simplecopier.StructToMapByJsonTag(resp)
	if err != nil {
		stark.Logger.Error(ctx, "获取模板配置repository 结果json解析失败", err)
		return nil, err
	}

	if _, ok := result["data"]; ok {
		tempateList := make([]map[string]interface{}, len(result["data"].([]interface{})))
		for i, item := range result["data"].([]interface{}) {
			if tempMap, ok := item.(map[string]interface{}); ok {
				tempateList[i] = tempMap
			} else {
				stark.Logger.Errorf(ctx, "模板配置解析失败，value:%v", result)
			}
		}
		return tempateList, nil
	} else {
		return nil, nil
	}
}

func (r *reportRepository) GetFormDataRule(ctx context.Context, key string) ([]map[string]interface{}, error) {
	request := &commonPb.GetFormDataRuleRequest{
		RuleIds: key,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := commonPb.NewFormServiceClient(conn)
	resp, err := client.GetFormDataRule(ctx, request)
	if err != nil {
		return nil, err
	}
	result, err := simplecopier.StructToMapByJsonTag(resp)
	if err != nil {
		return nil, err
	}

	if _, ok := result["data"]; ok {
		ruleList := make([]map[string]interface{}, len(result["data"].([]interface{})))
		for i, item := range result["data"].([]interface{}) {
			if tempMap, ok := item.(map[string]interface{}); ok {
				ruleList[i] = tempMap
			} else {
				stark.Logger.Errorf(ctx, "模板数据规则解析失败，value:%v", result)
			}
		}
		return ruleList, nil
	} else {
		return nil, nil
	}
}

func (r *reportRepository) GetUserList(ctx context.Context) (map[string]interface{}, error) {
	request := &cluePb.GetUserListRequest{}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := cluePb.NewReportServiceClient(conn)
	resp, err := client.GetUserList(ctx, request)
	if err != nil {
		return nil, err
	}

	result, err := simplecopier.StructToMapByJsonTag(resp)
	if err != nil {
		return nil, err
	}

	return result, nil
}

func (r *reportRepository) GenerateUrl(ctx context.Context, rs *report2.ReportShare) (string, error) {
	reportPb := &microGfyxUserService.ReportFromSharing{}
	simplecopier.CopyToStruct(reportPb, rs)
	request := &microGfyxUserService.GenerateUrlRequest{
		Report: reportPb,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_USER_SERVICE)
	if err != nil {
		return "", err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := microGfyxUserService.NewReportServiceClient(conn)
	res, err := client.GenerateUrl(ctx, request)

	if err != nil {
		return "", err
	}

	if res == nil {
		return "", nil
	}

	return res.GetCode(), nil
}

func (r *reportRepository) ReceiveUrl(ctx context.Context, userId, code string) (bool, error) {
	request := &microGfyxUserService.ReceiveUrlRequest{
		RecipientUid: userId,
		Code:         code,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_USER_SERVICE)
	if err != nil {
		return false, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := microGfyxUserService.NewReportServiceClient(conn)
	res, err := client.ReceiveUrl(ctx, request)
	if err != nil {
		return false, err
	}
	if res == nil {
		return false, nil
	}

	return res.GetIsSuccess(), nil
}

func (r *reportRepository) ReportFromSharingList(ctx context.Context, reqDto *reportDto.ReportFromSharingListRequestDto) (int64, []*microGfyxUserService.ReportFromSharing, error) {
	request := &microGfyxUserService.ReportFromSharingListRequest{
		Page:             reqDto.Page,
		PageSize:         reqDto.PageSize,
		RecipientUid:     reqDto.RecipientUid,
		ProvinceCode:     reqDto.ProvinceCode,
		CityCode:         reqDto.CityCode,
		ReportStatusCode: reqDto.ReportStatusCode,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_USER_SERVICE)
	if err != nil {
		return 0, nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := microGfyxUserService.NewReportServiceClient(conn)
	res, err := client.ReportFromSharingList(ctx, request)
	if err != nil {
		return 0, nil, err
	}
	if res == nil {
		return 0, nil, nil
	}

	return res.Total, res.Reports, nil
}

func (r *reportRepository) ReportInfo(ctx context.Context, condition *reportDto.ReportInfoRequestDto) (*microGfyxUserService.ReportFromSharing, error) {
	request := &microGfyxUserService.ReportInfoRequest{
		Code:     condition.Code,
		ReportId: condition.ReportId,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_USER_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := microGfyxUserService.NewReportServiceClient(conn)
	res, err := client.ReportInfo(ctx, request)
	if err != nil {
		return nil, err
	}

	if res == nil {
		return nil, nil
	}

	return res.GetReport(), nil
}

func (r *reportRepository) SearchContacts(ctx context.Context, params *reportDto.SearchContactRequest) (*http_client.BigDataResponse, error) {
	resultData := &http_client.BigDataResponse{}
	header := map[string]string{}

	if params.PageSize == 0 {
		params.PageSize = 10
	}
	bigdataParamsMap, err := simplecopier.StructToMapByJsonTag(params)
	if err != nil {
		return resultData, err
	}
	_, _, errs := http_client.NewBigdataApiHttpClient().Post(ctx, constants.SearchContacts, bigdataParamsMap, header).EndStruct(&resultData)
	if len(errs) > 0 {
		return nil, errs[0]
	}

	return resultData, nil
}

func (r *reportRepository) GetTeamLeader(ctx context.Context, reportId string) (map[string]interface{}, error) {
	request := &cluePb.GetTeamLeaderRequest{
		ReportUid: reportId,
	}
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := cluePb.NewReportServiceClient(conn)
	resp, err := client.GetTeamLeader(ctx, request)
	if err != nil {
		return nil, err
	}

	result, err := simplecopier.StructToMapByJsonTag(resp)
	if err != nil {
		return nil, err
	}

	return result, nil
}

func (r *reportRepository) FillReportForm(ctx context.Context, params *reportDto.FillReportFormRequest) (*http_client.BigDataResponseList, error) {
	resultData := &http_client.BigDataResponseList{}
	header := map[string]string{}

	bigdataParamsMap, err := simplecopier.StructToMapByJsonTag(params)
	if err != nil {
		return resultData, err
	}

	var errs []error
	if strings.EqualFold(params.ClueSource, "developer") || strings.EqualFold(params.ClueSource, "supplier") {
		_, _, errs = http_client.NewBigdataApiHttpClient().Post(ctx, constants.GetFillDeveloperReportUrl, bigdataParamsMap, header).EndStruct(&resultData)
	} else if params.ClueSource == "purchase" {
		_, _, errs = http_client.NewBigdataApiHttpClient().Post(ctx, constants.GetFillPurchaseReportUrl, bigdataParamsMap, header).EndStruct(&resultData)
	} else if params.ClueSource == "winbid" {
		_, _, errs = http_client.NewBigdataApiHttpClient().Post(ctx, constants.GetFillWinbidReportUrl, bigdataParamsMap, header).EndStruct(&resultData)
	} else if params.ClueSource == "land" {
		_, _, errs = http_client.NewBigdataApiHttpClient().Post(ctx, constants.GetFillLandReportUrl, bigdataParamsMap, header).EndStruct(&resultData)
	} else if params.ClueSource == "building" {
		//只有在建项目的clueSourceId是拼接的， 用id和prj_num两个字段用下划线拼接的，在查询es时，需要把id切出来
		clueSourceId := strings.Split(params.ClueSourceId, "_")[0]
		bigdataParamsMap["clue_source_id"] = clueSourceId
		_, _, errs = http_client.NewBigdataApiHttpClient().Post(ctx, constants.GetFillBuildingReportUrl, bigdataParamsMap, header).EndStruct(&resultData)
	} else if params.ClueSource == "project" {
		_, _, errs = http_client.NewBigdataApiHttpClient().Post(ctx, constants.GetFillProjectReportUrl, bigdataParamsMap, header).EndStruct(&resultData)
	} else if params.ClueSource == "sale" {
		_, _, errs = http_client.NewBigdataApiHttpClient().Post(ctx, constants.GetFillSaleReportUrl, bigdataParamsMap, header).EndStruct(&resultData)
	}

	if len(errs) > 0 {
		return nil, errs[0]
	}

	return resultData, nil
}

func (r *reportRepository) GetReportSourceInfo(ctx context.Context, sourceType, sourceId string) (map[string]interface{}, error) {
	request := &cluePb.GetReportSourceInfoRequest{
		ReportSourceType: sourceType,
		ReportSourceId:   sourceId,
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := cluePb.NewReportServiceClient(conn)
	resp, err := client.GetReportSourceInfo(ctx, request)
	if err != nil {
		return nil, err
	}

	if resp == nil {
		return nil, nil
	}

	result, err := simplecopier.StructToMapByJsonTag(resp)
	if err != nil {
		return nil, err
	}

	if value, ok := result["project_image"]; ok && value.(string) != "" {
		result["project_image"] = strings.Split(value.(string), ",")
	} else {
		result["project_image"] = make([]string, 0)
	}

	return result, nil
}

func (r *reportRepository) Save(ctx context.Context, saveReq *reportDto.SaveRequest) (bool, string, error) {
	request := &cluePb.SaveReportRequest{
		ReportSourceType:        saveReq.ReportSourceType,
		ReportSourceId:          saveReq.ReportSourceId,
		CompanyName:             saveReq.CompanyName,
		CompanyOrganizingCode:   saveReq.CompanyOrganizingCode,
		CompanyType:             saveReq.CompanyType,
		CompanyCityCode:         saveReq.CompanyCityCode,
		CompanyProvinceCode:     saveReq.CompanyProvinceCode,
		DefaultContact:          saveReq.DefaultContact,
		DefaultContactTel:       saveReq.DefaultContactTel,
		ContactPosition:         saveReq.ContactPosition,
		ProjectTitle:            saveReq.ProjectTitle,
		ProjectType:             saveReq.ProjectType,
		ProjectAddress:          saveReq.ProjectAddress,
		ProjectProvinceCode:     saveReq.ProjectProvinceCode,
		ProjectCityCode:         saveReq.ProjectCityCode,
		ProjectImage:            strings.Join(saveReq.ProjectImage, ","),
		SubmitterCompany:        saveReq.SubmitterCompany,
		Submitter:               saveReq.Submitter,
		SubmitterTel:            saveReq.SubmitterTel,
		AgencyName:              saveReq.AgencyName,
		AgencyContact:           saveReq.AgencyContact,
		AgencyContactTel:        saveReq.AgencyContactTel,
		ResponsiblePersonGuid:   saveReq.ResponsiblePersonGuid,
		ResponsiblePersonName:   saveReq.ResponsiblePersonName,
		ResponsiblePersonMobile: saveReq.ResponsiblePersonMobile,
		ProjectProvince:         saveReq.ProjectProvince,
		ProjectCity:             saveReq.ProjectCity,
		ClueSource:              saveReq.ClueSource,
		ClueSourceId:            saveReq.ClueSourceId,
	}
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return false, "", err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := cluePb.NewReportServiceClient(conn)
	resp, err := client.SaveReport(ctx, request)
	if err != nil {
		return false, "", err
	}
	if resp == nil {
		return false, "", nil
	}

	return resp.IsSuccess, resp.ReportId, nil
}

func (r *reportRepository) GetReport(ctx context.Context, reportId string) (*cluePb.GetReportResponse, error) {
	request := cluePb.GetReportRequest{
		ReportId: reportId,
	}
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := cluePb.NewReportServiceClient(conn)
	return client.GetReport(ctx, &request)
}

func (r *reportRepository) GetReportList(ctx context.Context, request *reportDto.ReportMyListRequestDto) (*cluePb.GetReportListResponse, error) {
	params := &cluePb.GetReportListRequest{
		ResponsiblePersonGuid: authorize.GetTenantUserId(ctx),
		Keyword:               request.Keyword,
		ProjectProvinceCode:   request.ProjectProvinceCode,
		ProjectCityCode:       request.ProjectCityCode,
		CompanyProvinceCode:   request.CompanyProvinceCode,
		CompanyCityCode:       request.CompanyCityCode,
		SubmitStartTime:       request.SubmitStartTime,
		SubmitEndTime:         request.SubmitEndTime,
		FollowStatus:          int32(request.FollowStatus),
		Page:                  int32(request.Page),
		PageSize:              int32(request.PageSize),
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := cluePb.NewReportServiceClient(conn)
	return client.GetReportList(ctx, params)
}

func (r *reportRepository) GetRegionReportList(ctx context.Context, request *reportDto.ReportMyListRequestDto) (*cluePb.GetReportListResponse, error) {
	params := &cluePb.GetReportListRequest{
		UserId:                authorize.GetTenantUserId(ctx),
		ResponsiblePersonGuid: request.ResponsiblePersonGuid,
		Keyword:               request.Keyword,
		ProjectProvinceCode:   request.ProjectProvinceCode,
		ProjectCityCode:       request.ProjectCityCode,
		CompanyProvinceCode:   request.CompanyProvinceCode,
		CompanyCityCode:       request.CompanyCityCode,
		SubmitStartTime:       request.SubmitStartTime,
		SubmitEndTime:         request.SubmitEndTime,
		FollowStatus:          int32(request.FollowStatus),
		Page:                  int32(request.Page),
		PageSize:              int32(request.PageSize),
	}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := cluePb.NewReportServiceClient(conn)
	return client.GetRegionReportList(ctx, params)
}

func (r *reportRepository) GetReportStat(ctx context.Context) (*cluePb.MyReportStatResponse, error) {
	request := cluePb.MyReportStatRequest{}

	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_OPPTY_SERVICE)
	if err != nil {
		return nil, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := cluePb.NewReportServiceClient(conn)
	return client.MyReportStat(ctx, &request)
}

func (r *reportRepository) UpdateReportShare(ctx context.Context, userUid string, code string, data *microGfyxUserService.ReportFromSharing) (bool, error) {
	request := &microGfyxUserService.UpdateReportShareRequest{
		RecipientUid: userUid,
		Code:         code,
		Status:       data,
	}
	conn, ctx, err := rpc_client.GetClientConn(ctx, constants.MICRO_GFYX_USER_SERVICE)
	if err != nil {
		return false, err
	}
	defer func() {
		_ = conn.Close()
	}()
	client := microGfyxUserService.NewReportServiceClient(conn)
	_, err = client.UpdateReportShare(ctx, request)
	if err != nil {
		stark.Logger.Errorf(ctx, "UpdateReportShare-error: %+v, request: %+v", request, err)
		return false, err
	}

	return true, nil
}
